package com.justreading.order.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.justreading.order.constant.CarImagesSeparatorConstant;
import com.justreading.order.constant.MessageConstant;
import com.justreading.order.entity.*;
import com.justreading.order.service.*;
import com.justreading.order.vo.response.GetTravelListResponse;
import com.justreading.order.vo.response.TravelListResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.justreading.common.utils.PageUtils;
import com.justreading.common.utils.Query;

import com.justreading.order.dao.TravelListDao;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;


@Service("travelListService")
public class TravelListServiceImpl extends ServiceImpl<TravelListDao, TravelListEntity> implements TravelListService {

    @Autowired
    private CarService carService;

    @Autowired
    private UserService userService;

    @Autowired
    private TravelOrderService travelOrderService;

    @Autowired
    private MessageService messageService;

    private static final String TAG_01 = "您预订的: ";

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Long userId = Long.parseLong(params.get("userId").toString());
        int page = Integer.parseInt(params.get("page").toString());
        int limit = Integer.parseInt(params.get("limit").toString());
        int current = page;
        if (current != 0) {
            current = limit * current;
        }
        List<TravelListEntity> travelListEntities = this.baseMapper.pageList(current, limit, userId);
        List<TravelListResponse> list = travelListEntities.stream().map((entity) -> {
            TravelListResponse travelListResponse = new TravelListResponse();
            CarEntity carEntity = carService.getById(entity.getCarId());
            BeanUtils.copyProperties(entity, travelListResponse);
            travelListResponse.setLicensePlate(carEntity.getLicensePlate());
            return travelListResponse;
        }).collect(Collectors.toList());
        Page<TravelListResponse> travelListResponsePage = new Page<>(page, limit);
        travelListResponsePage.setRecords(list);
        return new PageUtils(travelListResponsePage);
    }

    @Override
    public PageUtils getTravelList(Map<String, Object> params) {
        IPage<TravelListEntity> travelListEntityIPage = this.page(new Query<TravelListEntity>().getPage(params),
                new QueryWrapper<TravelListEntity>().orderByDesc("create_time"));
        List<GetTravelListResponse> getTravelList = travelListEntityIPage.getRecords().stream().map((entity) -> {
            Long carId = entity.getCarId();
            Long userId = entity.getUserId();
            CarEntity carEntity = carService.getById(carId);
            UserEntity userEntity = userService.getById(userId);
            return copyProperties(entity, carEntity, userEntity);
        }).collect(Collectors.toList());
        Page<GetTravelListResponse> getTravelListResponsePage = new Page<>(travelListEntityIPage.getCurrent(), travelListEntityIPage.getSize(), travelListEntityIPage.getTotal());
        getTravelListResponsePage.setRecords(getTravelList);
        return new PageUtils(getTravelListResponsePage);
    }

    /**
     * 订单新建之后可以发生修改，但是要通知到出行者们,车主自己更改不需要通知
     *
     * @param travelList
     */
    @Transactional
    @Override
    public void updateTravelListAndSendMessage(TravelListEntity travelList) {
        Integer status = travelList.getStatus();
        List<TravelOrderEntity> travelOrderEntities = travelOrderService.list(new QueryWrapper<TravelOrderEntity>().eq("travel_list_id", travelList.getId()));
        TravelListEntity oldTravelList = this.getById(travelList.getId());
        if (!ObjectUtils.isEmpty(travelOrderEntities)) {
            sendMessage(travelList, travelOrderEntities, status, oldTravelList);
        }
        this.updateById(travelList);
    }


    private void sendMessage(TravelListEntity travelList, List<TravelOrderEntity> travelOrderEntities, Integer status, TravelListEntity oldTravelList) {
        List<MessageEntity> messageEntities = new ArrayList<>();
        switch (status) {
            case 0:
                for (TravelOrderEntity travelOrderEntity : travelOrderEntities) {
                    if (!travelOrderEntity.getOrderStatus().equals(4)) {
                        travelOrderEntity.setOrderStatus(status);
                        MessageEntity messageEntity = new MessageEntity();
                        messageEntity.setReceiveUserId(travelOrderEntity.getTravelOrderUserId());
                        messageEntity.setSendUserId(travelList.getUserId());
                        messageEntity.setContent(TAG_01 + oldTravelList.getBoardingPoint() + "——>" + oldTravelList.getTravelPoint() + MessageConstant.ORDER_UPDATE);
                        messageEntities.add(messageEntity);
                    }
                }
            case 1:
                for (TravelOrderEntity travelOrderEntity : travelOrderEntities) {
                    if (!travelOrderEntity.getOrderStatus().equals(4)) {
                        travelOrderEntity.setOrderStatus(status);
                        MessageEntity messageEntity = new MessageEntity();
                        messageEntity.setReceiveUserId(travelOrderEntity.getTravelOrderUserId());
                        messageEntity.setSendUserId(travelList.getUserId());
                        messageEntity.setContent(TAG_01 + travelList.getBoardingPoint() + "——>" + travelList.getTravelPoint() + MessageConstant.ORDER_START);
                        messageEntities.add(messageEntity);
                    }
                }
                travelOrderService.updateBatchById(travelOrderEntities);
                break;
            case 2:
                for (TravelOrderEntity travelOrderEntity : travelOrderEntities) {
                    if (!travelOrderEntity.getOrderStatus().equals(4)) {
                        travelOrderEntity.setOrderStatus(status);
                        MessageEntity messageEntity = new MessageEntity();
                        messageEntity.setReceiveUserId(travelOrderEntity.getTravelOrderUserId());
                        messageEntity.setSendUserId(travelList.getUserId());
                        messageEntity.setContent(TAG_01 + travelList.getBoardingPoint() + "——>" + travelList.getTravelPoint() + MessageConstant.ORDER_END);
                        messageEntities.add(messageEntity);
                    }
                }
                travelOrderService.updateBatchById(travelOrderEntities);
                break;
            case 3:
                for (TravelOrderEntity travelOrderEntity : travelOrderEntities) {
                    if (!travelOrderEntity.getOrderStatus().equals(4)) {
                        travelOrderEntity.setOrderStatus(status);
                        MessageEntity messageEntity = new MessageEntity();
                        messageEntity.setReceiveUserId(travelOrderEntity.getTravelOrderUserId());
                        messageEntity.setSendUserId(travelList.getUserId());
                        messageEntity.setContent(TAG_01 + travelList.getBoardingPoint() + "——>" + travelList.getTravelPoint() + MessageConstant.ORDER_CANCEL);
                        messageEntities.add(messageEntity);
                    }
                }
                travelOrderService.updateBatchById(travelOrderEntities);
                break;
            case 4:
                for (TravelOrderEntity travelOrderEntity : travelOrderEntities) {
                    if (!travelOrderEntity.getOrderStatus().equals(4)) {
                        travelOrderEntity.setOrderStatus(status);
                        MessageEntity messageEntity = new MessageEntity();
                        messageEntity.setReceiveUserId(travelOrderEntity.getTravelOrderUserId());
                        messageEntity.setSendUserId(travelList.getUserId());
                        messageEntity.setContent(TAG_01 + travelList.getBoardingPoint() + "——>" + travelList.getTravelPoint() + MessageConstant.ORDER_EXPIRATION);
                        messageEntities.add(messageEntity);
                    }
                }
                break;
            default:
                break;
        }
        messageService.saveBatch(messageEntities);
    }

    /**
     * @param travelListEntity 出行单
     * @param carEntity        车辆
     * @param userEntity       发单人
     * @return GetTravelListResponse
     */
    private GetTravelListResponse copyProperties(TravelListEntity travelListEntity, CarEntity carEntity, UserEntity userEntity) {
        GetTravelListResponse getTravelListResponse = new GetTravelListResponse();
        BeanUtils.copyProperties(travelListEntity, getTravelListResponse);
        getTravelListResponse.setLicensePlate(carEntity.getLicensePlate());
        String images = carEntity.getImages();
        String[] imgList = images.split(CarImagesSeparatorConstant.CAR_SEPARATOR_1);
        getTravelListResponse.setImageList(Arrays.asList(imgList));
        getTravelListResponse.setDescription(carEntity.getDescription());
        getTravelListResponse.setColor(carEntity.getColor());
        getTravelListResponse.setTrueName(userEntity.getTrueName());
        getTravelListResponse.setMobile(userEntity.getMobile());
        getTravelListResponse.setHeader(userEntity.getHeader());
        getTravelListResponse.setGender(userEntity.getGender());
        getTravelListResponse.setSchool(userEntity.getSchool());
        getTravelListResponse.setCollege(userEntity.getCollege());
        getTravelListResponse.setJobId(userEntity.getJobId());
        getTravelListResponse.setReleaseNumber(userEntity.getReleaseNumber());
        getTravelListResponse.setReleaseNumber(userEntity.getReleaseNumber());
        getTravelListResponse.setGrowth(userEntity.getGrowth());
        getTravelListResponse.setIntegration(userEntity.getIntegration());
        getTravelListResponse.setComplianceRate(userEntity.getComplianceRate());
        return getTravelListResponse;
    }

}